package com.xianyun.site.support.executor.handle.smtp;

import com.aliyuncs.dm.model.v20151123.BatchSendMailRequest;
import com.aliyuncs.dm.model.v20151123.SingleSendMailRequest;
import com.xianyun.common.core.text.Convert;
import com.xianyun.common.core.utils.StringUtils;
import com.xianyun.common.core.utils.io.IoUtils;
import com.xianyun.common.redis.service.RedisService;
import com.xianyun.site.support.common.exception.SmtpException;
import com.xianyun.site.support.domain.model.SmtpMessage;
import com.xianyun.site.support.gatewayimpl.database.SmtpConfigMapper;
import com.xianyun.site.support.gatewayimpl.database.SmtpTemplateMapper;
import com.xianyun.site.support.gatewayimpl.database.domainobject.SmtpConfig;
import com.xianyun.site.support.gatewayimpl.database.domainobject.SmtpTemplate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;

/**
 * 邮件策略
 * @author mac_zyj
 */
@Slf4j
@Component
public abstract class BaseSmtpStrategy {
    /**Redis服务*/
    @Autowired
    private RedisService redisService;

    @Autowired
    protected SmtpConfigMapper smtpConfigMapper;

    @Autowired
    protected SmtpTemplateMapper smtpTemplateMapper;

    /**
     * 生成简单邮件请求
     * @param message 邮件参数
     * @return 简单邮件对象
     */
    public abstract SingleSendMailRequest sendSingleMailRequest(SmtpMessage message);

    /**
     * 生成模板邮件请求
     * @return 模板邮件请求
     */
    public abstract BatchSendMailRequest sendBatchMailRequest();

    /**
     * 通过OSS软链接方式获取Html发送体内容
     * @param fileKey 文件索引
     * @param url 文件路径
     * @return
     */
    protected String getHtmlBodyByUrl(String fileKey,String url)  {
        try{
            InputStream mailTemplateStream = checkCacheAndGetInput(fileKey,url);
            return getInputStreamToHtmlBody(mailTemplateStream);
        }catch (MalformedURLException urlException){
            log.warn("malformed url exception:{}", ExceptionUtils.getStackTrace(urlException));
            throw new SmtpException("路径解析失败！");
        } catch (IOException ioException) {
            log.warn("IO exception:{}",ExceptionUtils.getStackTrace(ioException));
            throw new SmtpException("IO异常！");
        }
    }

    protected SingleSendMailRequest initSingleSendMail(SmtpMessage message){
        SmtpConfig smtpConfig = smtpConfigMapper.selectSmtpConfigByName(message.getConditionName());
        SmtpTemplate smtpTemplate = smtpTemplateMapper.selectSmtpTemplateByName(message.getConditionName());
        Assert.notNull(smtpConfig,"请检查参数配置");
        Assert.notNull(smtpTemplate,"请检查参数配置");
        SingleSendMailRequest request = smtpConfig.initNoReplyRequest();
        request.setToAddress(message.getToAddress());
        request.setSubject(smtpTemplate.getTitle());
        message.setFileKey(smtpTemplate.getFileName()+smtpTemplate.getVersion());
        message.setFileLocation(smtpTemplate.getTemplateLocal());
        return request;
    }

    private InputStream checkCacheAndGetInput(String fileKey,String url) throws IOException {
        String cacheResult = redisService.getCacheObject(fileKey);
        if (StringUtils.isNotEmpty(cacheResult)){
            redisService.setCacheObject(fileKey,cacheResult,1, TimeUnit.DAYS);
        }
        else {
            // 上传网络流。
            cacheResult = Convert.str(IoUtils.toByteArray(new URL(url).openStream()),"gbk");
            redisService.setCacheObject(fileKey,cacheResult,3, TimeUnit.DAYS);
        }
        return new ByteArrayInputStream(cacheResult.getBytes());
    }


    private String getInputStreamToHtmlBody(InputStream mailTemplateStream){
        Scanner scanner = new Scanner(mailTemplateStream);
        StringBuilder htmlBody = new StringBuilder();
        while (scanner.hasNextLine()) {
            //去除空格 否则调用接口会报异常
            String currentLine= scanner.nextLine().replace("  ", "");
            htmlBody.append(currentLine);
        }
        return htmlBody.toString();
    }
}
